.. role:: raw-html-m2r(raw) :format: html Registers ========= Introduction ------------ Creating registers in SpinalHDL is very different than in VHDL or Verilog. In Spinal, there are no process/always blocks. Registers are explicitly defined at declaration. This difference from traditional event-driven HDL has a big impact: * You can assign registers and wires in the same scope, meaning the code doesn't need to be split between process/always blocks * It make things much more flexible (see :ref:`Functions `) Clocks and resets are handled separately, see the :ref:`Clock domain ` chapter for details. Instantiation ------------- There are 4 ways to instantiate a register: .. list-table:: :header-rows: 1 :widths: 50 55 * - Syntax - Description * - ``Reg(type : Data)`` - Register of the given type * - ``RegInit(resetValue : Data)`` - Register loaded with the given ``resetValue`` when a reset occurs * - ``RegNext(nextValue : Data)`` - Register that samples the given ``nextValue`` each cycle * - ``RegNextWhen(nextValue : Data, cond : Bool)`` - Register that samples the given ``nextValue`` when a condition occurs Here is an example declaring some registers: .. code-block:: scala // UInt register of 4 bits val reg1 = Reg(UInt(4 bit)) // Register that samples reg1 each cycle val reg2 = RegNext(reg1 + 1) // UInt register of 4 bits initialized with 0 when the reset occurs val reg3 = RegInit(U"0000") reg3 := reg2 when(reg2 === 5) { reg3 := 0xF } // Register that samples reg3 when cond is True val reg4 = RegNextWhen(reg3, cond) The code above will infer the following logic: .. image:: /asset/picture/register.svg :align: center .. note:: The ``reg3`` example above shows how you can assign the value of a ``RegInit`` register. It's possible to use the same syntax to assign to the other register types as well (``Reg``, ``RegNext``, ``RegNextWhen``). Just like in combinational assignments, the rule is 'Last assignment wins', but if no assignment is done, the register keeps its value. Also, ``RegNext`` is an abstraction which is built over the ``Reg`` syntax. The two following sequences of code are strictly equivalent: .. code-block:: scala // Standard way val something = Bool() val value = Reg(Bool()) value := something // Short way val something = Bool() val value = RegNext(something) Reset value ----------- In addition to the ``RegInit(value : Data)`` syntax which directly creates the register with a reset value, you can also set the reset value by calling the ``init(value : Data)`` function on the register. .. code-block:: scala // UInt register of 4 bits initialized with 0 when the reset occurs val reg1 = Reg(UInt(4 bit)) init(0) If you have a register containing a Bundle, you can use the ``init`` function on each element of the Bundle. .. code-block:: scala case class ValidRGB() extends Bundle{ val valid = Bool() val r, g, b = UInt(8 bits) } val reg = Reg(ValidRGB()) reg.valid init(False) // Only the valid if that register bundle will have a reset value. Initialization value for simulation purposes -------------------------------------------- For registers that don't need a reset value in RTL, but need an initialization value for simulation (to avoid x-propagation), you can ask for a random initialization value by calling the ``randBoot()`` function. .. code-block:: scala // UInt register of 4 bits initialized with a random value val reg1 = Reg(UInt(4 bit)) randBoot()